"""
@Author: li
@Email: lijianqiao2906@live.com
@FileName: cache.py
@DateTime: 2025/07/16 00:00:00
@Docs: 缓存管理器
"""

from functools import wraps
from typing import Any

from app.utils.logger import logger


class CacheManager:
    """缓存管理器"""

    def __init__(self):
        self._cache = {}
        self._default_ttl = 300  # 5分钟

    def get(self, key: str) -> Any | None:
        """获取缓存值"""
        try:
            if key in self._cache:
                value, expiry = self._cache[key]
                if expiry is None or self._is_valid(expiry):
                    logger.debug(f"Cache hit: {key}")
                    return value
                else:
                    # 过期，删除缓存
                    del self._cache[key]
                    logger.debug(f"Cache expired and removed: {key}")
            return None
        except Exception as e:
            logger.error(f"Cache get error: {e}")
            return None

    def set(self, key: str, value: Any, ttl: int | None = None) -> bool:
        """设置缓存值"""
        try:
            ttl = ttl or self._default_ttl
            expiry = self._get_expiry(ttl)
            self._cache[key] = (value, expiry)
            logger.debug(f"Cache set: {key} (TTL: {ttl}s)")
            return True
        except Exception as e:
            logger.error(f"Cache set error: {e}")
            return False

    def delete(self, key: str) -> bool:
        """删除缓存"""
        try:
            if key in self._cache:
                del self._cache[key]
                logger.debug(f"Cache deleted: {key}")
                return True
            return False
        except Exception as e:
            logger.error(f"Cache delete error: {e}")
            return False

    def clear(self) -> bool:
        """清空缓存"""
        try:
            self._cache.clear()
            logger.debug("Cache cleared")
            return True
        except Exception as e:
            logger.error(f"Cache clear error: {e}")
            return False

    def exists(self, key: str) -> bool:
        """检查缓存是否存在"""
        return self.get(key) is not None

    def _get_expiry(self, ttl: int) -> float:
        """获取过期时间戳"""
        from time import time

        return time() + ttl

    def _is_valid(self, expiry: float) -> bool:
        """检查缓存是否有效"""
        from time import time

        return time() < expiry

    def cache_key(self, prefix: str, *args) -> str:
        """生成缓存键"""
        key_parts = [prefix] + [str(arg) for arg in args]
        return ":".join(key_parts)


def cache_result(ttl: int = 300, key_prefix: str | None = None):
    """缓存装饰器

    Args:
        ttl: 缓存时间（秒）
        key_prefix: 缓存键前缀
    """

    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            cache = cache_manager

            # 生成缓存键
            prefix = key_prefix or func.__name__
            cache_key = cache.cache_key(prefix, *args, *[f"{k}:{v}" for k, v in kwargs.items()])

            # 尝试从缓存获取
            cached_result = cache.get(cache_key)
            if cached_result is not None:
                return cached_result

            # 执行函数并缓存结果
            result = await func(*args, **kwargs)
            cache.set(cache_key, result, ttl)
            return result

        return wrapper

    return decorator


def invalidate_cache(pattern: str = "*"):
    """使缓存失效"""
    cache = cache_manager
    keys_to_delete = [k for k in cache._cache.keys() if pattern in k]
    for key in keys_to_delete:
        cache.delete(key)
    logger.info(f"Invalidated {len(keys_to_delete)} cache keys with pattern: {pattern}")


# 全局缓存管理器实例
cache_manager = CacheManager()
